package parDef

import (
	"context"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"db2s/go-log/log"
	"db2s/ref"
)

func getTableName(schema, table any) (tableName string) {
	return fmt.Sprintf(" %v.%v ", schema, table)
}
func getSysObjectView(p ...string) (sysView []string) {
	return p
}
func generalQuerySysObjectSql(s, t string, o []string, body func(o, s, t string) string) (res []string) {
	for _, v := range o {
		res = append(res, body(v, s, t))
	}
	return
}
func GetExecFuncParameterValueBase(ctx context.Context) (schema, table string) {
	schema = GetParameterValueAnyToString(GetFuncParameterValue(ctx, GetSchemaParameterValue()))
	table = GetParameterValueAnyToString(GetFuncParameterValue(ctx, GetTableParameterValue()))
	return
}
func GetExecFuncParameterValueBaseP(ctx context.Context) (schema, table, partition string) {
	schema, table = GetExecFuncParameterValueBase(ctx)
	partition = GetParameterValueAnyToString(GetFuncParameterValue(ctx, GetPartitionParameterValue()))
	return
}
func GetReadExecSqlFuncOptionsValueBase(ctx context.Context) (res ETL.ReadOpt) {
	return GetReadDbExecOptions(GetFuncParameterValue(ctx, GetDbReadOptionsParameterValue()))
}
func GetWriteExecSqlFuncOptionsValueBase(ctx context.Context) (res ETL.WriteOpt) {
	return GetWriteDbExecOptions(GetFuncParameterValue(ctx, GetDbWriteOptionsParameterValue()))
}
func NewGetExternalExecFuncParameterValue(ctx context.Context, event string, res global.Return, funcParameter any, funcDef any) (eventNew string, schemaTable string, externalExecFunc func(s any, execFunc any) (any, error), result global.Return, funcParameterNew any, funcDefNew any) {
	externalExecFunc = GetExternalExecFunc(GetFuncParameterValue(ctx, GetExternalExecFuncParameterValue()))
	return event, getTableName(GetExecFuncParameterValueBase(ctx)), externalExecFunc, res, funcParameter, funcDef
}
func GetJsonNameValue(getJsonValue func(s any, key string) (any, error), meta any, name string) (result string) {
	var rr any
	var err error
	if getJsonValue != nil {
		if rr, err = getJsonValue(meta, name); err != nil {
			return
		}
	}
	return fmt.Sprintf("%v", rr)
}
func GetSqlQueryExecFuncParameterValue(ctx context.Context, event string, objectView []string, body func(o string, s string, t string) string, GisValFunc func(any) any) (eventNew string, schemaTable string, newCtx context.Context, dbOptions any, pp func(any) any, execSqlFunc func(ctx context.Context, S any, GisValFunc func(any) any, sessionOptions, sqlStr []string, expect string) (global.Return, error), sessionOptions, execSql []string, expect string) {
	var schema, table = GetExecFuncParameterValueBase(ctx)
	execSql = generalQuerySysObjectSql(schema, table, getSysObjectView(objectView...), body)
	dbOptions = GetReadExecSqlFuncOptionsValueBase(ctx)
	expect = GetParameterValueAnyToString(GetFuncParameterValue(ctx, GetExpectParameterValue()))
	execSqlFunc = GetDbExecSqlFunc(GetFuncParameterValue(ctx, GetExecSqlFuncParameterValue()))
	return event, getTableName(schema, table), ctx, dbOptions, GisValFunc, execSqlFunc, sessionOptions, execSql, expect
}
func GetSubSqlExecFuncParameterValue(ctx context.Context, event, expectOld string, objectView []string, body func(o string, s string, t string) string, GisValFunc func(any) any) (eventNew string, schemaTable string, newCtx context.Context, dbOptions any, pp func(any) any, execSqlFunc func(ctx context.Context, S any, GisValFunc func(any) any, sessionOptions, sqlStr []string, expect string) (global.Return, error), sessionOptions, execSql []string, expect string) {
	var schema, table = GetExecFuncParameterValueBase(ctx)
	execSql = generalQuerySysObjectSql(schema, table, getSysObjectView(objectView...), body)
	dbOptions = GetReadExecSqlFuncOptionsValueBase(ctx)
	if len(expectOld) == 0 {
		expect = GetParameterValueAnyToString(GetFuncParameterValue(ctx, GetExpectParameterValue()))
	} else {
		expect = expectOld
	}
	execSqlFunc = GetDbExecSqlFunc(GetFuncParameterValue(ctx, GetExecSqlFuncParameterValue()))
	return event, getTableName(schema, table), ctx, dbOptions, GisValFunc, execSqlFunc, sessionOptions, execSql, expect
}

func SqlExec(event string, schemaTable string, ctx context.Context, dbOptions any, GisValFunc func(any) any, execSqlFunc func(ctx context.Context, S any, GisValFunc func(any) any, sessionOptions, sqlStr []string, expect string) (global.Return, error), sessionOptions, execSql []string, expect string) (result global.Return, err error) {
	log.MainLog().DebugS(event, schemaTable, fmt.Sprintf(" sql is %v.", execSql))
	if execSqlFunc == nil {
		log.MainLog().WarnSS(event, schemaTable, fmt.Sprintf(" ExecSqlFunc is nil."))
		return
	}
	if result, err = execSqlFunc(ctx, dbOptions, GisValFunc, sessionOptions, execSql, expect); err != nil {
		err = ref.ErrAddPrintf(event, err)
		log.ErrorLog().ErrorSS(event, schemaTable, fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
		return
	}
	log.MainLog().DebugSS(event, schemaTable, fmt.Sprintf(" sql is %v, bath timeOut is %v ms,query result is %v.", result.Sql, result.TimeOut, result.Result))
	return
}
func ResultExec(event string, schemaTable string, execFunc func(s any, execFunc any) (any, error), res global.Return, funcParameter any, funcDef any) (result global.Return, err error) {
	result = res
	if execFunc == nil {
		log.MainLog().WarnSS(event, schemaTable, fmt.Sprintf(" ExecFunc is nil."))
		return
	}
	if result.Result, err = execFunc(funcParameter, funcDef); err != nil {
		err = ref.ErrAddPrintf(event, err)
		log.ErrorLog().ErrorSS(event, schemaTable, fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
		return
	}
	log.MainLog().DebugSS(event, schemaTable, fmt.Sprintf(" sql is %v, bath timeOut is %v ms,query result is %v.", result.Sql, result.TimeOut, result.Result))
	return
}
